import { ElNotification } from 'element-plus';
import { getToken } from '@/store/modules/auth/helper';

var socket: any = null; //实例对象
var lockReconnect = false; //是否真正建立连接
var timeout = 20 * 1000; //20秒一次心跳
var timeoutObj: any = null; //心跳倒计时
var serverTimeoutObj: any = null; //服务心跳倒计时
var timeoutnum: any = null; //断开 重连倒计时

export const initWebSocket = async () => {
  if ('WebSocket' in window) {
    const wsUrl = import.meta.env.VITE_GLOB_APP_WEBSOCKET + '/' + JSON.parse(localStorage.getItem('msgprofile') || '{}')?.wx_id;
    socket = new WebSocket(wsUrl);
    socket.onerror = webSocketOnError;
    socket.onmessage = webSocketOnMessage;
    socket.onclose = closeWebsocket;
    socket.onopen = openWebsocket;
  } else {
    ElNotification.error({
      title: '错误',
      message: '您的浏览器不支持websocket，请更换Chrome或者Firefox'
    });
  }
};

//建立连接
const openWebsocket = (e: any) => {
  start();
};

const start = () => {
  //开启心跳
  timeoutObj && clearTimeout(timeoutObj);
  serverTimeoutObj && clearTimeout(serverTimeoutObj);
  timeoutObj = setTimeout(function () {
    //这里发送一个心跳，后端收到后，返回一个心跳消息
    console.log('ping');

    if (socket.readyState == 1) {
      //如果连接正常
      // socket.send("heartbeat");
    } else {
      //否则重连
      reconnect();
    }

    serverTimeoutObj = setTimeout(function () {
      //超时关闭
      socket.close();
    }, timeout);
  }, timeout);
};

//重新连接
export const reconnect = () => {
  if (lockReconnect) {
    return;
  }
  lockReconnect = true;
  //没连接上会一直重连，设置延迟避免请求过多
  timeoutnum && clearTimeout(timeoutnum);
  timeoutnum = setTimeout(function () {
    //新连接
    initWebSocket();
    lockReconnect = false;
  }, 5000);
};

//重置心跳
const reset = () => {
  //清除时间
  clearTimeout(timeoutObj);
  clearTimeout(serverTimeoutObj);
  //重启心跳
  start();
};

export const sendWebsocket = (e: any) => {
  socket.send(e);
};

const webSocketOnError = (e: any) => {
  initWebSocket();
  reconnect();
};

//服务器返回的数据
export const webSocketOnMessage = (e: any) => {
  //判断是否登录
  if (getToken()) {
    //window自定义事件[下面有说明]
    window.dispatchEvent(
      new CustomEvent('onmessageWS', {
        detail: {
          data: e?.data
        }
      })
    );
  }
  reset();
};

const closeWebsocket = (e: any) => {
  reconnect();
};

//断开连接
export const close = () => {
  //WebSocket对象也有发送和关闭的两个方法，只需要在自定义方法中分别调用send()和close()即可实现。
  socket.close();
};
//具体问题具体分析,把需要用到的方法暴露出去
